
#ifndef CHORDGOD_H_

#define CHORDGOD_H_

#include "common.h"
#include "object.h"

class ChordNode;
class KeyTuple;

struct ChordNetInfo{
	ChordNetInfo() : key_tuples_(NULL){}
	chord_net_id_t net_id_;
	TNodeIDVector  nodes_;
	KeyTuple      *key_tuples_;
	uint32_t	   number_of_keys_;	
};

typedef std::vector<ChordNetInfo> TChordNetInfoVector;

struct NodeKey{
	chord_node_id_t chord_nid_;
	int number_of_keys_;
};

class ChordGod : public Object{
	public:
		virtual ~ChordGod(){}
		bool init();
		bool initChord();
		
		static bool create();
		static void destroy();
		static ChordGod& instance(){ return *instance_; }

		ChordNode* getNodeInChordNet( chord_net_id_t net_id, node_id_t excluded );
		bool       registerToChordNet( chord_net_id_t net_id, node_id_t node_id );
		bool       unregisterToChordNet( chord_net_id_t net_id, node_id_t node_id );
		bool	   unregisterKeyToChordNet( chord_net_id_t net_id, chord_key_t key );
		bool	   isKeyOnline( chord_net_id_t net_id, chord_key_t key );

		uint32_t   numberOfChordNet() const { return (uint32_t)chord_nets_.size(); }
		uint32_t   getKeySpaceSize( chord_net_id_t net_id );

		void       startMerge();

		void	   nodeOnline(ChordNode *cn);
		void	   nodeOffline(ChordNode *cn);
		uint32_t   onlineCount() const;
		uint32_t   maxOnlineCount() const;
		uint32_t   onlineKeyCount() const;

		void	dumpChordNet();
		void	dumpLoad();

		ChordNetInfo& getNetInfo( chord_net_id_t net_id );

	protected:
		ChordGod(){}
		void generateKeys( int power_of_n, int number_of_key );
		void fill( ChordNetInfo& info );
		void fill_seq( ChordNetInfo& info );
		void assignKeys();

	protected:
		static ChordGod *instance_;
		TChordNetInfoVector chord_nets_;
		std::vector<TChordNodeVector> chord_nodes_;
		std::vector<std::vector<uint32_t> > random_key_list_;
		uint32_t online_cnt_;
		uint32_t max_online_cnt_;
		uint32_t online_key_cnt_;

};

#endif /* CHORDGOD_H_ */

